package com.microframework.netty.model;

import java.io.Serializable;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 客户端信息类，包含客户端的各种属性和状态信息
 */
public class ClientInfo implements Serializable {
	private static final long serialVersionUID = 1L;

	// 基础信息
	private final String clientId;
	private final String clientVersion;
	private final String clientType;
	private final long startupTime;

	// 网络信息
	private String hostName;
	private String hostAddress;
	private int clientPort;

	// 系统信息
	private String osName;
	private String osVersion;
	private String osArch;
	private int availableProcessors;
	private long maxMemory;
	private long freeMemory;
	private long totalMemory;

	// 运行时信息
	private String javaVersion;
	private String javaVendor;

	// 自定义元数据
	private Map<String, Object> metadata;

	// 状态信息
	private long lastActiveTime;
	private int connectionCount;
	private String status;

	/**
	 * 构造函数
	 * 
	 * @param clientId      客户端唯一ID
	 * @param clientVersion 客户端版本
	 * @param clientType    客户端类型
	 * @param startupTime   启动时间戳
	 */
	public ClientInfo(String clientId, String clientVersion, String clientType, long startupTime) {
		this.clientId = clientId;
		this.clientVersion = clientVersion;
		this.clientType = clientType;
		this.startupTime = startupTime;
		this.metadata = new HashMap<>();
		this.status = "INITIALIZING";

		// 收集系统信息
		collectSystemInfo();
		collectNetworkInfo();
		collectRuntimeInfo();
	}

	public ClientInfo(String clientId, String clientVersion, long startupTime, String clientType,
			Map<String, Object> metadata) {
		this.clientId = clientId;
		this.clientVersion = clientVersion;
		this.clientType = clientType;
		this.startupTime = startupTime;
		this.metadata = metadata != null ? new HashMap<>(metadata) : new HashMap<>();
		collectSystemInfo();
		collectNetworkInfo();
		collectRuntimeInfo();
	}

	/**
	 * 收集系统信息
	 */
	private void collectSystemInfo() {
		Properties props = System.getProperties();
		this.osName = props.getProperty("os.name");
		this.osVersion = props.getProperty("os.version");
		this.osArch = props.getProperty("os.arch");

		Runtime runtime = Runtime.getRuntime();
		this.availableProcessors = runtime.availableProcessors();
		this.maxMemory = runtime.maxMemory();
		this.freeMemory = runtime.freeMemory();
		this.totalMemory = runtime.totalMemory();
	}

	/**
	 * 收集网络信息
	 */
	private void collectNetworkInfo() {
		try {
			InetAddress localHost = InetAddress.getLocalHost();
			this.hostName = localHost.getHostName();
			this.hostAddress = localHost.getHostAddress();
		} catch (UnknownHostException e) {
			this.hostName = "unknown";
			this.hostAddress = "unknown";
		}
	}

	/**
	 * 收集运行时信息
	 */
	private void collectRuntimeInfo() {
		Properties props = System.getProperties();
		this.javaVersion = props.getProperty("java.version");
		this.javaVendor = props.getProperty("java.vendor");
	}

	/**
	 * 更新运行时状态
	 */
	public void updateRuntimeStatus() {
		Runtime runtime = Runtime.getRuntime();
		this.freeMemory = runtime.freeMemory();
		this.totalMemory = runtime.totalMemory();
		this.lastActiveTime = System.currentTimeMillis();
	}

	// ========== Getter 方法 ==========

	public String getClientId() {
		return clientId;
	}

	public String getClientVersion() {
		return clientVersion;
	}

	public String getClientType() {
		return clientType;
	}

	public long getStartupTime() {
		return startupTime;
	}

	public String getHostName() {
		return hostName;
	}

	public String getHostAddress() {
		return hostAddress;
	}

	public int getClientPort() {
		return clientPort;
	}

	public String getOsName() {
		return osName;
	}

	public String getOsVersion() {
		return osVersion;
	}

	public String getOsArch() {
		return osArch;
	}

	public int getAvailableProcessors() {
		return availableProcessors;
	}

	public long getMaxMemory() {
		return maxMemory;
	}

	public long getFreeMemory() {
		return freeMemory;
	}

	public long getTotalMemory() {
		return totalMemory;
	}

	public String getJavaVersion() {
		return javaVersion;
	}

	public String getJavaVendor() {
		return javaVendor;
	}

	public Map<String, Object> getMetadata() {
		return new HashMap<>(metadata);
	}

	public long getLastActiveTime() {
		return lastActiveTime;
	}

	public int getConnectionCount() {
		return connectionCount;
	}

	public String getStatus() {
		return status;
	}

	// ========== Setter 方法 ==========

	public void setClientPort(int clientPort) {
		this.clientPort = clientPort;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public void incrementConnectionCount() {
		this.connectionCount++;
	}

	// ========== 元数据操作方法 ==========

	public void addMetadata(String key, Object value) {
		this.metadata.put(key, value);
	}

	public Object getMetadata(String key) {
		return this.metadata.get(key);
	}

	public void removeMetadata(String key) {
		this.metadata.remove(key);
	}

	// ========== 工具方法 ==========

	/**
	 * 获取客户端运行时间（毫秒）
	 */
	public long getUptime() {
		return System.currentTimeMillis() - startupTime;
	}

	/**
	 * 获取内存使用率（0-1）
	 */
	public double getMemoryUsage() {
		return (totalMemory - freeMemory) / (double) totalMemory;
	}

	/**
	 * 获取客户端摘要信息
	 */
	public String getSummary() {
		return String.format("%s(v%s)@%s:%d", clientType, clientVersion, hostAddress, clientPort);
	}

	@Override
	public String toString() {
		return "ClientInfo{" + "clientId='" + clientId + '\'' + ", clientVersion='" + clientVersion + '\''
				+ ", clientType='" + clientType + '\'' + ", hostAddress='" + hostAddress + '\'' + ", status='" + status
				+ '\'' + ", uptime=" + getUptime() + "ms" + ", memoryUsage="
				+ String.format("%.2f%%", getMemoryUsage() * 100) + '}';
	}

	/**
	 * 生成详细报告
	 */
	public Map<String, Object> toDetailedMap() {
		Map<String, Object> details = new HashMap<>();

		// 基础信息
		details.put("clientId", clientId);
		details.put("clientVersion", clientVersion);
		details.put("clientType", clientType);
		details.put("startupTime", startupTime);
		details.put("uptime", getUptime());
		details.put("status", status);

		// 网络信息
		Map<String, Object> network = new HashMap<>();
		network.put("hostName", hostName);
		network.put("hostAddress", hostAddress);
		network.put("clientPort", clientPort);
		details.put("network", network);

		// 系统信息
		Map<String, Object> system = new HashMap<>();
		system.put("osName", osName);
		system.put("osVersion", osVersion);
		system.put("osArch", osArch);
		system.put("availableProcessors", availableProcessors);
		details.put("system", system);

		// 内存信息
		Map<String, Object> memory = new HashMap<>();
		memory.put("maxMemory", maxMemory);
		memory.put("totalMemory", totalMemory);
		memory.put("freeMemory", freeMemory);
		memory.put("memoryUsage", getMemoryUsage());
		details.put("memory", memory);

		// Java环境
		Map<String, Object> java = new HashMap<>();
		java.put("javaVersion", javaVersion);
		java.put("javaVendor", javaVendor);
		details.put("java", java);

		// 运行时状态
		Map<String, Object> runtime = new HashMap<>();
		runtime.put("lastActiveTime", lastActiveTime);
		runtime.put("connectionCount", connectionCount);
		details.put("runtime", runtime);

		// 元数据
		details.put("metadata", new HashMap<>(metadata));

		return details;
	}
}